
using System;

namespace Habazie.kf2.Exposition
{
	
	/// <summary>
	/// 	A TreeView with a few extras
	/// </summary>
	public class UltraTreeView : Gtk.TreeView
	{
		
		/// <summary>
		/// 	Public constructor
		/// </summary>
		public UltraTreeView() : base ()
		{
		}
		
		
		private uint tooltip_id = 0;
		private int tooltip_x = 0;
		private int tooltip_y = 0;
		private NotifyWindow tooltip = null;
		
		
		/// <summary>
		///		Get iter at specified position
		/// </summary>
		protected virtual Gtk.TreeIter GetIter (int x, int y)
		{
			Gtk.TreePath path;
			if (GetPathAtPos (x, y, out path)) {
				Gtk.TreeIter iter;
				if (Model.GetIter (out iter, path)) {
					return iter;
				}
			}
			return Gtk.TreeIter.Zero;
		}
		
		/// <summary>
		/// 	User moves mouse pointer over roster view
		/// </summary>
		protected override bool OnMotionNotifyEvent (Gdk.EventMotion evnt)
		{
			if (tooltip_id > 0) {
				/* Remove old timeout */
				GLib.Source.Remove (tooltip_id);
				tooltip_id = 0;
			}
			
			tooltip_id = GLib.Timeout.Add (800, TooltipTimeout);
			tooltip_x = (int)evnt.X;
			tooltip_y = (int)evnt.Y;
			
			return base.OnMotionNotifyEvent (evnt);
		}
		
		
		/// <summary>
		/// 	User moves mouse pointer away from roster view
		///	</summary>
		protected override bool OnLeaveNotifyEvent (Gdk.EventCrossing evnt)
		{
			if (tooltip_id > 0) {					// cancel timeout
				/* Remove old timeout */
				GLib.Source.Remove (tooltip_id);
				tooltip_id = 0;
			}

			if (tooltip != null)					// hide tooltip
				HideTooltip ();
				
			return base.OnLeaveNotifyEvent (evnt);
		}
		
		
		///	<summary>
		/// 	User holds mouse pointer for some period of time.
		/// 	Set up tooltip window
		/// </summary>
		protected virtual bool TooltipTimeout ()
		{
			if (tooltip != null)
				HideTooltip ();
	
			Gtk.TreeIter iter;
			iter = GetIter (tooltip_x, tooltip_y);
			ShowTooltip (iter);

			return false;
		}
		
		
		/// <summary>
		/// 	Show a tool tip
		/// </summary>
		protected virtual void ShowTooltip (Gtk.TreeIter iter)
		{
			string text;
			string desc;
			Gdk.Pixbuf pix;
			
			if (! QueryTooltip (iter, out text, out desc, out pix))
				return;
			
			tooltip = new NotifyWindow ();
			
			tooltip.TextMarkup = "<b><big>" + text + "</big></b>";
			tooltip.DescMarkup = desc;
			tooltip.Pixbuf = pix;
			
			int x,y, tx, ty; Gdk.ModifierType mask;
			this.Screen.RootWindow.GetPointer (out x, out y, out mask);
			tooltip.ComputeSize (out tx, out ty);
			if (x > this.Screen.Width - tx - 16)	// fit to screen
				x = this.Screen.Width - tx - 16;
			else
				x = x - 16;
			if (y > this.Screen.Height - ty - 16)
				y = y - ty - 16;
			else
				y = y + 16;
			
			tooltip.Move (x, y);
			
			tooltip.Show ();
		}
		
		
		/// <summary>
		/// 	Get tooltip contents
		/// </summary>
		protected virtual bool QueryTooltip (Gtk.TreeIter iter, out string text, out string desc, out Gdk.Pixbuf pix)
		{
			text = "";
			desc = "";
			pix = null;
			return false;
		}
		
		
		/// <summary>
		/// 	Hide tool tip
		/// </summary>
		protected virtual void HideTooltip ()
		{
			tooltip.Hide ();
			tooltip = null;
		}
	}
}
